#include "drv_btn.h"

#define BTN_1_PIN       LL_GPIO_PIN_5
#define BTN_1_PROT      GPIOB

#define BTN_A_PIN       LL_GPIO_PIN_8
#define BTN_A_PROT      GPIOA

#define BTN_B_PIN       LL_GPIO_PIN_4
#define BTN_B_PROT      GPIOA

volatile static drv_btn_cb_t drv_btn_cb;

void drv_btn_init(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    LL_EXTI_InitTypeDef EXTI_InitStruct = {0};

    GPIO_InitStruct.Pin     = BTN_1_PIN;
    GPIO_InitStruct.Mode    = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull    = LL_GPIO_PULL_UP;
    LL_GPIO_Init(BTN_1_PROT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin     = BTN_A_PIN;
    LL_GPIO_Init(BTN_A_PROT, &GPIO_InitStruct);
     
    GPIO_InitStruct.Pin     = BTN_B_PIN;
    LL_GPIO_Init(BTN_B_PROT, &GPIO_InitStruct);  

    EXTI_InitStruct.Line        = LL_EXTI_LINE_5 | LL_EXTI_LINE_8;
    EXTI_InitStruct.LineCommand = ENABLE;
    EXTI_InitStruct.Mode        = LL_EXTI_MODE_IT_EVENT;
    EXTI_InitStruct.Trigger     = LL_EXTI_TRIGGER_RISING_FALLING;
    LL_EXTI_Init(&EXTI_InitStruct);

    LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTB, LL_EXTI_CONFIG_LINE5);
    LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTA, LL_EXTI_CONFIG_LINE8);

    NVIC_SetPriority(EXTI4_15_IRQn, 0);
    NVIC_EnableIRQ(EXTI4_15_IRQn);
}

void drv_btn_irq_handler(drv_btn_type_t type)
{
    if (drv_btn_cb) {
        if (SET == drv_btn_read_level(type)) {
            drv_btn_cb(type, BTN_STATE_HIGH);
        } else {
            drv_btn_cb(type, BTN_STATE_LOW);
        }
    }
}

void drv_btn_cb_register(drv_btn_cb_t cb)
{
    drv_btn_cb = cb;
}

unsigned int drv_btn_read_level(drv_btn_type_t type)
{
    unsigned int pin[BTN_MAX] = {BTN_1_PIN, BTN_A_PIN, BTN_B_PIN};
    GPIO_TypeDef *port = NULL;

    if (type == BTN_1) {
        port = BTN_1_PROT;
    }
    else if (type == BTN_A) {
        port = BTN_A_PROT;
    }
    else if (type == BTN_B) {
        port = BTN_B_PROT;
    }
    return LL_GPIO_IsInputPinSet(port, pin[type]);
}




